package com.xxg.imagemanager.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

/**
 * Qps访问模块
 *
 * @author xuxiaogang
 * @date 2021-12-15
 */
public class QpsComponent {
    private final Logger logger = LoggerFactory.getLogger(QpsComponent.class);
    private final QpsController qpsController;

    public QpsComponent(int limit) {
        qpsController = new QpsController(limit);
    }

    /**
     * 尝试获取QPS
     *
     * @param timeout 等待时间 毫秒
     * @return 结果
     */
    public boolean tryAcquireQps(long timeout) {
        try {
            if (qpsController.getReentrantLock().tryLock(timeout, TimeUnit.MILLISECONDS)) {
                getQps();
                return true;
            } else {
                return false;
            }
        } catch (InterruptedException e) {
            logger.error(e.getMessage(), e);
            return false;
        } finally {
            qpsController.getReentrantLock().unlock();
        }
    }

    /**
     * 获取QPS
     */
    public void acquireQps() {
        try {
            qpsController.getReentrantLock().lock();
            getQps();
        } catch (InterruptedException e) {
            logger.error(e.getMessage(), e);
        } finally {
            qpsController.getReentrantLock().unlock();
        }
    }

    /**
     * 获取到qps后的处理
     *
     * @throws InterruptedException 异常信息
     */
    private void getQps() throws InterruptedException {
        long ct = System.currentTimeMillis();
        if (ct >= qpsController.getT()) {
            qpsController.reset();
        } else {
            int num = qpsController.getCount() % qpsController.getLimit();
            if (num == 0) {
                long dt = qpsController.getT() - System.currentTimeMillis();
                if (dt > 0) {
                    Thread.sleep(dt);
                }
                qpsController.reset();
            } else {
                qpsController.increaseCount();
            }
        }
    }
}
